/*
 *  logic.cpp
 *  
 *  Created by James Dykstra
 *	Team 5
 *
 *  Copyright 2010 Michigan Technological University. All rights reserved.
 */
#include "logic.h"
#include "sprite.h"

Logic::Logic(Renderer *rnd, Map* m)
{
	renderer = rnd;
	map = m;
}
Logic::~Logic()
{
}

bool Logic::checkCollide(Sprite *sprite, MapObstacle *obst) {
	if (sprite!=0 && obst!=0) {
		int leftA, leftB;
		int rightA, rightB;
		int topA, topB;
		int bottomA, bottomB;
		
		leftA = sprite->getRect()->x;
		leftB = obst->getTile()->position->x;
		rightA = leftA + sprite->getRect()->w;
		rightB = leftB + map->getTileWidth();
		topA = sprite->getRect()->y;
		topB = obst->getTile()->position->y;
		bottomA = topA + sprite->getRect()->h;
		bottomB = topB + map->getTileHeight();
		
		if(bottomA <= topB)
			return false;
		if(topA >= bottomB)
			return false;
		if(rightA <= leftB)
			return false;
		if(leftA >= rightB)
			return false;
		
		return overlapPixelScan(sprite->getSurface(), leftA, topA, rightA, bottomA, obst->getTile()->tileBackground, leftB, topB, rightB, bottomB);
	}
	else {
		return false;
	}
}

bool Logic::checkCollide(Sprite *spr1, Sprite *spr2)
{
	if(spr1!=0 && spr2!=0)
	{
		int leftA, leftB;
		int rightA, rightB;
		int topA, topB;
		int bottomA, bottomB;

		leftA = spr1->getRect()->x;
		leftB = spr2->getRect()->x;
		rightA = spr1->getRect()->x + spr1->getRect()->w;
		rightB = spr2->getRect()->x + spr2->getRect()->w;
		topA = spr1->getRect()->y;
		topB = spr2->getRect()->y;
		bottomA = spr1->getRect()->y + spr1->getRect()->h;
		bottomB = spr2->getRect()->y + spr2->getRect()->h;

		if(bottomA <= topB)
			return false;
		if(topA >= bottomB)
			return false;
		if(rightA <= leftB)
			return false;
		if(leftA >= rightB)
			return false;

		return overlapPixelScan(spr1->getSurface(), leftA, topA, rightA, bottomA, spr2->getSurface(), leftB, topB, rightB, bottomB);
	}
	else
		return false;
}
bool Logic::overlapPixelScan(SDL_Surface *spr1, int leftA, int topA, int rightA, int bottomA, SDL_Surface *spr2, int leftB, int topB, int rightB, int bottomB)
{
	if(spr1 != NULL && spr2 != NULL)
	{
		SDL_Rect overlap;
		if(leftB>leftA)
		{
			overlap.x = leftB;
			overlap.w = (rightA-leftB);
		}
		else
		{
			overlap.x = leftA;
			overlap.w = (rightB-leftA);
		}

		if(topB>topA)
		{
			overlap.y = topB;
			overlap.h = (bottomA-topB);
		}
		else
		{
			overlap.y = topA;
			overlap.h = (bottomB-topA);
		}
		
		for(int w=0; w<overlap.w; w++)
		{
			for(int h=0; h<overlap.h; h++)
			{
				if(renderer->getPixelAt(spr1, (w+(overlap.x-leftA)), (h+(overlap.y-topA))) != SDL_MapRGBA(spr1->format, 0, 255, 255, 0))
					if(renderer->getPixelAt(spr2, (w+(overlap.x-leftB)), (h+(overlap.y-topB))) != SDL_MapRGBA(spr2->format, 0, 255, 255, 0))
						return true;
			}
		}
	}

	return false;
}

bool Logic::validMove(Sprite * sprite, int xOffset, int yOffset)
{
	bool returnValue = true;
	sprite->getRect()->x += xOffset;
	sprite->getRect()->y += yOffset;
	do {
		if(((sprite->getRect()->x + sprite->getRect()->w) > map->getMapWidth()) || (sprite->getRect()->x < 0)) {
			returnValue=false;
			break;
		}
		
		if(((sprite->getRect()->y + sprite->getRect()->h) > map->getMapHeight()) || (sprite->getRect()->y < 0)) {
			returnValue=false;
			break;
		}
		
		for (int i=0; i<map->getNumObstacles(); i++) {
			if (checkCollide(sprite, map->getObstacle(i))) {
				returnValue = false;
				break;
			}
		}
	} while (false);
	
	sprite->getRect()->x -= xOffset;
	sprite->getRect()->y -= yOffset;
	
	return returnValue;
}
